package com.sav.common.localCatalog;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

import com.sav.common.catalog.Category;
import com.sav.common.dao.CategoryDAO;

public class Catalog {
	
	private static Catalog instance = null;
	private static int maxID = 0;
	private CategoryDAO categoryDAO = new CategoryDAO();
	
	private List<LocalCategory> listParentCategory;
	private List<Integer> listDeleted;

	public List<Integer> getListDeleted() {
		return listDeleted;
	}

	public void setListDeleted(List<Integer> listDeleted) {
		this.listDeleted = listDeleted;
	}

	public List<LocalCategory> getListParentCategory() {
		Collections.sort(listParentCategory);
		return listParentCategory;
	}

	public void setListParentCategory(List<LocalCategory> listParentCategory) {
		this.listParentCategory = listParentCategory;
	}
	
	public Catalog() {
		CategoryDAO categoryDAO = new CategoryDAO();
		List<Category> list = categoryDAO.getListParentCategory();
		listParentCategory = new ArrayList<LocalCategory>();
		for (Category c: list) {
			listParentCategory.add(new LocalCategory(c));
		}
		
		for (LocalCategory l : listParentCategory) {
			if (l.getIdCategory() > maxID) maxID = l.getIdCategory();
			for (LocalCategory l1 : l.getListSubCategory()) {
				if (l1.getIdCategory() > maxID) maxID = l1.getIdCategory();
			}
		}
		
		listDeleted = new ArrayList<Integer>();
	}
	
	public static Catalog getInstance() {
		if (instance == null)
			instance = new Catalog();
		return instance;
	}
	
	public static Catalog getWorkCatalog() {
		return new Catalog();
	}
	
	public LocalCategory getCategoryById(int id) {
		for (LocalCategory c: listParentCategory) {
			if (c.getIdCategory() == id) return c;
		}
		
		for (LocalCategory c: listParentCategory) {
			for (LocalCategory c1: c.getListSubCategory()) {
				if (c1.getIdCategory() == id) return c1;
			}
		}
		return null;
	}
	
	public void changeCategory(int id, String name, String description) {
		LocalCategory localCategory = getCategoryById(id);
		localCategory.setName(name);
		localCategory.setDescription(description);
	}
	
	public int addCategory(String name, String description, Integer idParent) {
		int orderNum;
		if (idParent == 0) {
			orderNum = getMaxOrderNum(listParentCategory);
			listParentCategory.add(new LocalCategory(name, description, null, orderNum));
		} else {
			LocalCategory localCategory = getCategoryById(idParent);
			orderNum = getMaxOrderNum(localCategory.getListSubCategory());
			localCategory.getListSubCategory().add(new LocalCategory(name, description, localCategory, orderNum));
		}
		return maxID;
	}
	
	public List<LocalCategory> getListSubCategory(int id) {
		LocalCategory localCategory = getCategoryById(id);
		if (localCategory == null) return null;
		Collections.sort(localCategory.getListSubCategory());
		return localCategory.getListSubCategory();
	}
	
	public int getCountProductsInCategory(int id) {
		int res = categoryDAO.getCountProductsInCategory(id);
		return res;
	}
	
	public boolean haveSubCategory(int id) {
		LocalCategory localCategory = getCategoryById(id);
		if (localCategory == null) return false;
		if (localCategory.getListSubCategory().size() == 0) 
			return false; else 
				return true;
	}
	
	public void swapCategory(Integer id1, Integer id2) {
		LocalCategory localCategory1 = getCategoryById(id1);
		LocalCategory localCategory2 = getCategoryById(id2);
		if ((localCategory1 == null) || (localCategory2 == null)) return;
		int orderNum1 = localCategory1.getOrderNum();
		int orderNum2 = localCategory2.getOrderNum();
		localCategory1.setOrderNum(orderNum2);
		localCategory2.setOrderNum(orderNum1);
	}
	
	public void deleteCategory(int id) {
		LocalCategory localCategory = getCategoryById(id);
		if (localCategory == null) return;
		LocalCategory parentCategory = localCategory.getParentCategory();
		if (parentCategory== null) 
			listParentCategory.remove(localCategory); else
				parentCategory.getListSubCategory().remove(localCategory);
		listDeleted.add(id);
	}
	
	public int getLevelNesting(int idParent) {
		if (idParent == 0) return 1;
		int level = 1;
		LocalCategory localCategory = getCategoryById(idParent);
		if (localCategory == null) return -1;
		do {
			level++;
			localCategory = localCategory.getParentCategory();
		}
		while (localCategory != null);
		return level;
	}
	
	public void saveWorkCatalog() {
		categoryDAO.saveChanges(this);
		instance = new Catalog();
	}
	
	public static int getMaxID() {
		return maxID;
	}
	
	public static void setMaxId(int maxid) {
		maxID = maxid;
	}
	
	public static void reload() {
		instance = new Catalog();
	}
	
	public static List<Category> listLocalCategoriesToListCategories(List<LocalCategory> listLocalCategories) {
		List<Category> list = new ArrayList<Category>();
		for (LocalCategory c : listLocalCategories) {
			int idParentCategory = 0;
			if (c.getParentCategory() != null) c.getParentCategory().getIdCategory();
			list.add(new Category(
				c.getIdCategory(), 
				idParentCategory,
				c.getName(), 
				c.getDescription(), 
				c.getOrderNum()));
		}
		return list;
	}
	
	public int getMaxOrderNum(List<LocalCategory> list) {
		int res = 0;
		for (LocalCategory c : list) {
			if (c.getOrderNum() > res) res = c.getOrderNum();
		}
		return ++res;
	}
	
}
